home *** CD-ROM | disk | FTP | other *** search
- ; Haffman decoding
- ; Written by Malakhov K.A.
- ; Compile with TASM 3.0 or latter
- ; TASM DARHH7.ASM /MX /ZX /O
- ; CALL: haff_decode(char *buffinput,unsigned int inputlength,
- ; char *buffoutput,unsigned int outputlength);
-
- model large
-
- PUBLIC _haff_decode
-
- .code
-
- _haff_decode PROC C FAR
- ARG buffi:dword,ileng:word,buffo:dword,oleng:word
- USES ds,es,di,si,bx,cx,dx
-
- ; main
- ; Allocate memory
- mov ah,48h
- mov bx,2049
- int 21h
- jnc @@impl_t000
- jmp @@imp_err
- @@impl_t000: mov cs:seg1,ax
- mov ah,48h
- mov bx,2049
- int 21h
- jnc @@impl_t001
- jmp @@imp_err
- @@impl_t001: mov cs:seg2,ax
- jmp @@main_1
- @@main_0: jmp @@imp_err
- @@main_1: mov ax,word ptr buffi+2
- mov ds,ax
- mov si,word ptr buffi
- mov ax,ileng
- cmp ax,0
- ja @@new_010
- jmp @@imp_err
- @@new_010: mov cs:counti,ax
- mov ax,word ptr buffo+2
- mov es,ax
- mov di,word ptr buffo
- mov ax,oleng
- mov cs:counto,ax
- cmp ax,0
- ja @@imp_005
- jmp @@imp_err
- @@imp_005:
- ; decompression
- call darhhaff
- cmp ax,0
- jne @@implode_e1
- @@implode_e: jmp @@imp_err
- @@implode_e1: jmp @@imp_exit
-
- darhhaff proc NEAR
- ; Read
- lodsb
- dec word ptr cs:counti
- push ax
- cmp cs:counti,0
- pop ax
- jne @@darh_001
- jmp @@implode_err
- @@darh_001: mov cs:CRCodr,al
- lodsb
- dec word ptr cs:counti
- push ax
- cmp cs:counti,0
- pop ax
- jne @@darh_010
- jmp @@implode_err
- ; Read the length of header
- @@darh_010: xor ah,ah
- inc ax
- mov cs:hafflen,ax
- mov dx,ax
- push cs
- pop es
- ; Clear tresh
- mov cx,256
- lea di,chartab
- xor ax,ax
- rep stosb
- mov cx,256
- lea di,freqtab
- rep stosw
- mov cx,1024
- lea di,hafftab
- rep stosb
- mov cx,dx
- mov cs:codcnt,0
- ; Read header chartab
- lea di,chartab
- @@darh_020: lodsb
- dec word ptr cs:counti
- push ax
- cmp cs:counti,0
- pop ax
- ja @@darh_030
- jmp @@implode_err
- @@darh_030: stosb
- loop @@darh_020
- ; Read header freqtab
- mov cx,cs:hafflen
- lea di,freqtab
- @@darh_040: lodsb
- dec word ptr cs:counti
- push ax
- cmp cs:counti,0
- pop ax
- ja @@darh_050
- jmp @@implode_err
- @@darh_050: xchg ah,al
- lodsb
- dec word ptr cs:counti
- push ax
- cmp cs:counti,0
- pop ax
- ja @@darh_055
- jmp @@implode_err
- @@darh_055: xchg ah,al
- stosw
- loop @@darh_040
- @@darh_057:
- mov cs:savesi,si
- ; Build the tree
- ; Prepare the table of weights
- mov cx,256
- lea di,codtab
- xor al,al
- rep stosb
- ; MIN
- @@impl_089: mov bx,65535
- xor si,si
- mov cx,cs:hafflen
- @@impl_090: mov ax,cs:freqtab[si]
- cmp ax,0
- je @@impl_092
- cmp bx,ax
- jbe @@impl_092
- mov bx,ax
- mov cs:minpos1,si
- @@impl_092: add si,2
- loop @@impl_090
-
- mov cs:exit,1
- mov bx,65535
- xor si,si
- mov cx,cs:hafflen
- cmp cx,1
- ja @@impl_094
- mov ax,cs:minpos1
- shr ax,1
- mov cl,1
- call shift
- jmp @@impl_220
- @@impl_094: mov ax,cs:freqtab[si]
- cmp ax,0
- je @@impl_096
- cmp bx,ax
- jb @@impl_096
- cmp si,cs:minpos1
- je @@impl_096
- mov bx,ax
- mov cs:exit,0
- mov cs:minpos2,si
- @@impl_096: add si,2
- loop @@impl_094
-
- mov al,cs:exit
- cmp al,0
- je @@impl_098
- jmp @@impl_220
- @@impl_098:
- mov ax,cs:minpos1
- shr ax,1
- mov si,ax
- mov ax,cs:minpos2
- shr ax,1
- mov di,ax
- mov al,cs:codtab[si]
- mov ah,cs:codtab[di]
- cmp al,0
- jne @@impl_100
- cmp ah,0
- je @@impl_099
- jmp @@impl_125
- ; Variant 1
- @@impl_099: inc byte ptr cs:codcnt
- mov ax,si
- mov cl,0
- call shift
- mov ax,di
- mov cl,1
- call shift
- mov al,cs:codcnt
- mov cs:codtab[si],al
- mov cs:codtab[di],al
- mov si,cs:minpos1
- mov di,cs:minpos2
- mov ax,cs:freqtab[di]
- add cs:freqtab[si],ax
- mov cs:freqtab[di],0
- jmp @@impl_089
- ; Variant 2
- @@impl_100:
- cmp ah,0
- je @@impl_102
- jmp @@impl_140
- @@impl_102:
- mov ax,cs:minpos1
- shr ax,1
- mov si,ax
- mov dl,cs:codtab[si]
- mov cx,256
- xor si,si
- @@impl_105: cmp dl,cs:codtab[si]
- jne @@impl_110
- push cx
- mov ax,si
- xor cl,cl
- call shift
- pop cx
- @@impl_110: inc si
- loop @@impl_105
-
- mov ax,cs:minpos2
- shr ax,1
- mov cl,1
- call shift
-
- mov ax,cs:minpos1
- shr ax,1
- mov si,ax
- mov ax,cs:minpos2
- shr ax,1
- mov di,ax
- mov al,cs:codtab[si]
- mov cs:codtab[di],al
-
- mov si,cs:minpos1
- mov di,cs:minpos2
- mov ax,cs:freqtab[di]
- add cs:freqtab[si],ax
- mov cs:freqtab[di],0
- jmp @@impl_089
- @@impl_125:
- mov ax,cs:minpos2
- shr ax,1
- mov si,ax
- mov dl,cs:codtab[si]
- mov cx,256
- xor si,si
- @@impl_130: cmp dl,cs:codtab[si]
- jne @@impl_135
- push cx
- mov ax,si
- xor cl,cl
- call shift
- pop cx
- @@impl_135: inc si
- loop @@impl_130
-
- mov ax,cs:minpos1
- shr ax,1
- mov cl,1
- call shift
-
- mov ax,cs:minpos2
- shr ax,1
- mov si,ax
- mov ax,cs:minpos1
- shr ax,1
- mov di,ax
- mov al,cs:codtab[si]
- mov cs:codtab[di],al
-
- mov si,cs:minpos2
- mov di,cs:minpos1
- mov ax,cs:freqtab[di]
- add cs:freqtab[si],ax
- mov cs:freqtab[di],0
- jmp @@impl_089
- ; Variant 3
- @@impl_140:
- mov ax,cs:minpos1
- shr ax,1
- mov si,ax
- mov dl,cs:codtab[si]
- mov cx,256
- xor si,si
- @@impl_145: cmp dl,cs:codtab[si]
- jne @@impl_150
- push cx
- mov ax,si
- xor cl,cl
- call shift
- pop cx
- @@impl_150: inc si
- loop @@impl_145
-
- mov ax,cs:minpos2
- shr ax,1
- mov si,ax
- mov dl,cs:codtab[si]
- mov cx,256
- xor si,si
- @@impl_155: cmp dl,cs:codtab[si]
- jne @@impl_160
- push cx
- mov ax,si
- mov cl,1
- call shift
- pop cx
- @@impl_160: inc si
- loop @@impl_155
-
- mov ax,cs:minpos1
- shr ax,1
- mov si,ax
- mov dl,cs:codtab[si]
- mov ax,cs:minpos2
- shr ax,1
- mov si,ax
- mov dh,cs:codtab[si]
- mov cx,256
- xor si,si
- @@impl_165: cmp dl,cs:codtab[si]
- jne @@impl_170
- mov cs:codtab[si],dh
- @@impl_170: inc si
- loop @@impl_165
-
- mov si,cs:minpos2
- mov di,cs:minpos1
- mov ax,cs:freqtab[di]
- add cs:freqtab[si],ax
- mov cs:freqtab[di],0
- jmp @@impl_089
- ; Calculating the number of bytes
- @@impl_220: mov di,2
- mov cx,256
- @@impl_230: mov al,cs:hafftab[di]
- xor ah,ah
- xor dx,dx
- mov bx,8
- div bx
- mov cs:hafftab[di],8
- cmp dx,0
- je @@impl_240
- mov cs:hafftab[di],dl
- inc ax
- @@impl_240: mov cs:hafftab[di+1],al
- add di,4
- loop @@impl_230
- ; The number of dearchieve bytes
- mov cx,256
- mov ax,es
- mov ds,ax
- lea si,freqtab
- mov cs:countb,0
- @@impl_245: lodsw
- add cs:countb,ax
- loop @@impl_245
- ; To fill the table
- mov cx,256
- mov ax,cs:seg1
- mov ds,ax
- mov ax,cs:seg2
- mov es,ax
- xor si,si
- @@impl_t010: push cx
- ; Mask
- mov dl,byte ptr cs:hafftab[si+3]
- cmp dl,0
- je @@impl_t040
- mov ax,0ffffh
- mov cl,3
- shl dl,cl
- mov cl,24
- sub cl,dl
- sub cl,byte ptr cs:hafftab[si+2]
- shl ax,cl
- mov cs:svsi,ax
- ; Word
- mov dh,byte ptr cs:hafftab[si]
- mov dl,byte ptr cs:hafftab[si+1]
- mov cs:svdi,dx
-
- @@impl_t020: mov ax,cs:svsi
- and ax,dx
- cmp ax,cs:svdi
- jne @@impl_t040
- mov bx,dx
- ; Direction betwin memory blocks
- cmp bx,32768
- ja @@impl_t030
- mov ax,si
- shr ax,1
- shr ax,1
- mov byte ptr ds:[bx],al
- inc dx
- jmp short @@impl_t020
- @@impl_t030: sub bx,32768
- mov ax,si
- shr ax,1
- shr ax,1
- mov byte ptr es:[bx],al
- inc dx
- jmp short @@impl_t020
- @@impl_t040: add si,4
- pop cx
- loop @@impl_t010
- ; Decoder
- mov cs:shiftb,0
- mov ax,oleng
- mov cs:counto,ax
- mov ax,word ptr buffi+2
- mov ds,ax
- mov si,cs:savesi
- mov ax,word ptr buffo+2
- mov es,ax
- mov di,word ptr buffo
- mov cs:CRCod,0
- ; Load the word
- @@impl_250: mov ah,ds:[si]
- mov al,ds:[si+1]
- mov dh,al
- mov dl,ds:[si+2]
- ; Shift
- @@impl_254: mov cl,cs:shiftb
- shl ax,cl
- shl dx,cl
- mov al,dh
-
- mov bx,ax
- cmp bx,32768
- ja @@impl_p010
- mov cx,cs:seg1
- jmp short @@impl_p020
- @@impl_p010: sub bx,32768
- mov cx,cs:seg2
- @@impl_p020: push ds
- mov ds,cx
- mov al,byte ptr ds:[bx]
- pop ds
- mov cs:svsi,si
- xor ah,ah
- mov si,ax
- ; Output from loop (found)
- @@impl_315:
- stosb
- add cs:CRCod,al
- dec word ptr cs:counto
- mov ax,cs:counto
- cmp ax,0
- ja @@impl_312
- jmp @@implode_err
- @@impl_312: dec word ptr cs:countb
- mov bx,si
- mov si,cs:svsi
- mov cl,2
- shl bx,cl
- add bx,3
- mov al,cs:hafftab[bx]
- dec al
- xor ah,ah
- add si,ax
- sub word ptr cs:counti,ax
- mov al,cs:hafftab[bx-1]
- mov ah,cs:shiftb
- add ah,al
-
- mov cx,cs:countb
- cmp cx,0
- je @@impl_318
-
- cmp ah,8
- jb @@impl_314
- sub ah,8
- inc si
- dec word ptr cs:counti
- @@impl_314: mov cs:shiftb,ah
- jmp @@impl_250
- ; Output
-
- @@impl_318:
- @@impl_320: mov ax,oleng
- sub ax,cs:counto
- cmp ax,0
- ja @@impl_330
- inc ax
- @@impl_330:
- @@implode_err: mov ax,0
- jmp short @@impl_exit
- @@implode_noerr:
- ; Check CRC
- mov bl,cs:CRCodr
- cmp bl,cs:CRCod
- je @@impl_exit
- mov ax,0
- @@impl_exit: ret
- darhhaff endp
-
- ; Procedure for set a mask
- maska proc NEAR
- push bx
- push cx
- push dx
- mov bx,si
- mov cl,2
- shl bx,cl
- add bx,3
- cmp dl,cs:hafftab[bx]
- jne @@maska_010
- dec bx
- mov cl,8
- sub cl,cs:hafftab[bx]
- mov dl,0ffh
- shl dl,cl
- and ah,dl
- @@maska_010: pop dx
- pop cx
- pop bx
- ret
- maska endp
-
- ; Shift procedure
- shift proc NEAR
- push bx
- push di
- push dx
- rcr cl,1
- pushf
- mov bx,ax
- mov al,cs:chartab[bx]
- xor ah,ah
- mov cl,2
- shl ax,cl
- mov di,ax
- xor bx,bx
- mov dx,bx
- add dx,1
- @@shift_010: cmp bx,dx
- ja @@shift_020
- mov al,cs:hafftab[di+bx]
- popf
- rcr al,1
- pushf
- mov cs:hafftab[di+bx],al
- inc bx
- jmp short @@shift_010
- @@shift_015: mov cs:errflag,1
- jmp short @@shift_030
- @@shift_020: popf
- mov cl,byte ptr cs:hafftab[di+bx]
- cmp cl,16
- ja @@shift_015
- @@shift_030: inc byte ptr cs:hafftab[di+bx]
- pop dx
- pop di
- pop bx
- ret
- shift endp
-
- ; Data
- counti dw ? ; Input bytes
- counto dw ? ; Output bytes
- countb dw ? ; Counter of bytes
- savesi dw ?
- hafflen dw ?
- errflag db ?
- shiftb db ?
- currhaff dw ?
- minpos1 dw ?
- minpos2 dw ?
- codcnt db ?
- exit db ?
- kajuk dw ?
- ident db 'MSI'
- CRCod db ?
- CRCodr db ?
- flag dw ?
- svsi dw ?
- svdi dw ?
- seg1 dw ? ; Address of heshing table
- seg2 dw ? ;
- chartab db 256 dup(?)
- freqtab dw 256 dup(?)
- codtab db 256 dup(?)
- hafftab db 1024 dup(?)
-
- @@imp_err: mov ax,0
- jmp short @@imp_exit
- @@imp_noerr:
- @@imp_exit: push ax
- mov ax,cs:seg1
- mov es,ax
- mov ah,49h
- int 21h
- mov ax,cs:seg2
- mov es,ax
- mov ah,49h
- int 21h
- pop ax
- ret
- _haff_decode ENDP
-
- END
-